function changeScore( points )
{
    var scoreContainer = document.getElementById( 'score' );
    var lastScore = parseInt( scoreContainer.value.substring(6, scoreContainer.value.length) );
    lastScore += points;
    scoreContainer.value = "Score: " + lastScore;
    
    return lastScore;
}

function changeLifes( points )
{
    var lifesContainer = document.getElementById( 'lifes' );
    var lastLifes = parseInt( lifesContainer.value.substring(6, lifesContainer.value.length) );
    lastLifes += points;
    lifesContainer.value = "Lifes: " + lastLifes;
    
    return lastLifes;
}

function changeTime()
{
    var timeContainer = document.getElementById( 'time' );
    var hours;
    var minutes;
    var seconds;
    function convertTimeNumber( number )
    {
        if ( number < 10 )
        {
            return "0" + number;
        }
        else
        {
            return number;
        }
    }
    
    g_timeSeconds++;
    if ( g_timeSeconds == 60 )
    {
        g_timeSeconds = 0;
        g_timeMinutes++;
        if ( g_timeMinutes == 60 )
        {
            g_timeMinutes = 0;
            g_timeHours++;
        }
    }    
    seconds = convertTimeNumber( g_timeSeconds );
    minutes = convertTimeNumber( g_timeMinutes );
    hours = convertTimeNumber( g_timeHours );
    timeContainer.value = "Time: " + hours + ":" + minutes + ":" + seconds;
}

function loseLife( tankObj )
{
    if ( tankObj.lifes >= 1 )
    {
        tankObj.lifes--;
        if ( tankObj == tank )
        {
            changeLifes( -1 );
            if ( changeLifes( 0 ) == 0 )
            {
                return false;
            }
        }
        return true;
    }
    else
    {
        if ( tankObj != tank )
        {
            changeScore( 1 );
        }
        return false;
    }
}

function updateObj( someObj )
{
    if ( !someObj.dead )
    {
        someObj.x += someObj.dX;
        someObj.y += someObj.dY;
    }
    if (( someObj.dX != 0 ) || ( someObj.dY != 0 ) || ( someObj.dead ))
    {
        someObj.anims[someObj.currAnim].timer++;
        if ( someObj.anims[someObj.currAnim].timer > someObj.anims[someObj.currAnim].speed )
        {
            someObj.anims[someObj.currAnim].timer = 1;
            someObj.frame++;
            if (( !someObj.dead ) && ( someObj.frame > someObj.anims[someObj.currAnim].frames ) )
            {
                someObj.frame = 0;
            }
        }
    }
}

function getRandomTurn( someObj )
{
    switch ( getRandomInt( 1, 4 ) )
    {
        case 1:
            someObj.turn( "right" );
        break;
        case 2:
            someObj.turn( "left" );
        break;
        case 3:
            someObj.turn( "down" );
        break;
        case 4:
            someObj.turn( "up" );
        break;
    }
}

function checkCollision( tankObj1, tankObj2, type ) // столкновение танков друг с другом
{
    var isCollision = false;

    if (( !tankObj1.dead ) && ( !tankObj2.dead ) && ( tankObj1 != tankObj2))
    {
        if (( tankObj1.x < tankObj2.x + tankObj2.width ) &&
            ( tankObj1.x + tankObj1.width > tankObj2.x ) &&
            ( tankObj1.y < tankObj2.y + tankObj2.height) &&
            ( tankObj1.y + tankObj1.height > tankObj2.y ))
        {
            if ( type == "tank" )
            {
            }
            // остановка движения
            if (( type != "rocket" ) && ( type != "tank" ))
            {
                tankObj1.dX = 0;
                tankObj1.dY = 0;
                tankObj2.dX = 0;
                tankObj2.dY = 0;
            }
            
            isCollision = true;
        }
    }
    
    return isCollision;
}

function checkWalls( someObj, type ) // столкновение танков со стенами
{
    // определяем координаты в массиве
    if (type == "rocket")
    {
        if ( someObj.dX < 0 )
        {
            var someObjI = (someObj.y / BLOCK_SIDE) - ((someObj.y / BLOCK_SIDE) % 1);
            var someObjJ = (someObj.x / BLOCK_SIDE) - ((someObj.x / BLOCK_SIDE) % 1) + 1;
        }
        else if ( someObj.dX > 0 )
        {
            var someObjI = (someObj.y / BLOCK_SIDE) - ((someObj.y / BLOCK_SIDE) % 1);
            var someObjJ = (someObj.x / BLOCK_SIDE) - ((someObj.x / BLOCK_SIDE) % 1) - 1;
        }
        if ( someObj.dY < 0 )
        {
            var someObjI = (someObj.y / BLOCK_SIDE) - ((someObj.y / BLOCK_SIDE) % 1) + 1;
            var someObjJ = (someObj.x / BLOCK_SIDE) - ((someObj.x / BLOCK_SIDE) % 1);
        }
        else if ( someObj.dY > 0 )
        {
            var someObjI = (someObj.y / BLOCK_SIDE) - ((someObj.y / BLOCK_SIDE) % 1) - 1;
            var someObjJ = (someObj.x / BLOCK_SIDE) - ((someObj.x / BLOCK_SIDE) % 1);
        }
    }
    else
    {
        var someObjI = Math.round( someObj.y / BLOCK_SIDE );
        var someObjJ = Math.round( someObj.x / BLOCK_SIDE );
    }
    var isWall = false;
    // проверяем клетку передвижения
    if ( someObj.dX > 0 ) // справа
    {
        if (( level[someObjI][someObjJ + 1].type == 1 ) && 
            ( someObj.x + someObj.width > level[someObjI][someObjJ + 1].x ))
        {
            someObj.x = level[someObjI][someObjJ + 1].x - someObj.width;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI + 1][someObjJ + 1].type == 1 ) && 
                   ( someObj.y + someObj.height > level[someObjI + 1][someObjJ + 1].y ) &&
                   ( someObj.x + someObj.width > level[someObjI + 1][someObjJ + 1].x ))
        {
            someObj.x = level[someObjI + 1][someObjJ + 1].x - someObj.width;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI - 1][someObjJ + 1].type == 1 ) && 
                   ( someObj.y < level[someObjI - 1][someObjJ + 1].y + BLOCK_SIDE ) &&
                   ( someObj.x + someObj.width > level[someObjI - 1][someObjJ + 1].x ))
        {
            someObj.x = level[someObjI - 1][someObjJ + 1].x - someObj.width;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        }
    } else if ( someObj.dX < 0 ) // слева
    {
        if (( level[someObjI][someObjJ - 1].type == 1 ) &&
            ( someObj.x < level[someObjI][someObjJ - 1].x + BLOCK_SIDE ))
        {
            someObj.x = level[someObjI][someObjJ - 1].x + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI + 1][someObjJ - 1].type == 1 ) && 
                   ( someObj.y + someObj.height > level[someObjI + 1][someObjJ - 1].y ) &&
                   ( someObj.x < level[someObjI + 1][someObjJ - 1].x + BLOCK_SIDE ))
        {
            someObj.x = level[someObjI][someObjJ - 1].x + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI - 1][someObjJ - 1].type == 1 ) && 
                   ( someObj.y < level[someObjI - 1][someObjJ - 1].y + BLOCK_SIDE ) &&
                   ( someObj.x < level[someObjI - 1][someObjJ - 1].x + BLOCK_SIDE ))
        {
            someObj.x = level[someObjI][someObjJ - 1].x + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        }
    }
    if ( someObj.dY > 0 ) // снизу
    {
        if (( level[someObjI + 1][someObjJ].type == 1 ) &&
            ( someObj.y + someObj.height > level[someObjI + 1][someObjJ].y ))
        {
            someObj.y = level[someObjI + 1][someObjJ].y - someObj.height;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI + 1][someObjJ - 1].type == 1 ) && 
                   ( someObj.x < level[someObjI + 1][someObjJ - 1].x + BLOCK_SIDE) &&
                   ( someObj.y + someObj.height > level[someObjI + 1][someObjJ - 1].y ))
        {
            someObj.y = level[someObjI + 1][someObjJ].y - someObj.height;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI + 1][someObjJ + 1].type == 1 ) && 
                   ( someObj.x + someObj.width > level[someObjI + 1][someObjJ + 1].x ) &&
                   ( someObj.y + someObj.height > level[someObjI + 1][someObjJ + 1].y ))
        {
            someObj.y = level[someObjI + 1][someObjJ].y - someObj.height;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        }
    } else if ( someObj.dY < 0 ) // сверху
    {
        if (( level[someObjI - 1][someObjJ].type == 1 ) &&
            ( someObj.y < level[someObjI - 1][someObjJ].y + BLOCK_SIDE ))
        {
            someObj.y = level[someObjI - 1][someObjJ].y + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI - 1][someObjJ - 1].type == 1 ) && 
                   ( someObj.x < level[someObjI - 1][someObjJ - 1].x + BLOCK_SIDE) &&
                   ( someObj.y < level[someObjI - 1][someObjJ - 1].y + BLOCK_SIDE ))
        {
            someObj.y = level[someObjI - 1][someObjJ].y + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        } else if (( level[someObjI - 1][someObjJ + 1].type == 1 ) && 
                   ( someObj.x + someObj.width > level[someObjI - 1][someObjJ + 1].x ) &&
                   ( someObj.y < level[someObjI - 1][someObjJ + 1].y + BLOCK_SIDE ))
        {
            someObj.y = level[someObjI - 1][someObjJ].y + BLOCK_SIDE;
            someObj.dX = 0;
            someObj.dY = 0;
            isWall = true;
        }
    }
    
    return isWall;
}

function left( tankObj )
{
    switch ( tankObj.direction )
    {
        case "left":
            tankObj.turn( "up" );
        break;
        case "right":
            tankObj.turn( "down" );
        break;
        case "up":
            tankObj.turn( "right" );
        break;
        case "down":
            tankObj.turn( "left" );
        break;
    }
}

function update()
{
    var i = 0;
    var j = 0;
    g_timer++;
    
    if( g_timer >= FPS )
    {
        g_timer = 0;
        changeTime();
    }    
    // обновление координат для танка игрока
    updateObj( tank );
    // обновление коордиант для ракет
    for ( i = 0; i < rockets.length; i++ )
    {
        updateObj( rockets[i] );
    }
    // обновление координат вражеских танков
    for ( i = 0; i < enemies.length; i++ )
    {
        enemies[i].pursue_enemies = false;
        updateObj( enemies[i] );
    }
    // Анимация смерти завершилась, удаляем ракету
    for ( i = 0; i < rockets.length; i++ )
    {
        if (( rockets[i].dead ) && ( rockets[i].frame >= rockets[i].anims[rockets[i].currAnim].frames ))
        {
            rockets.splice ( i, 1 );
        }
    }
    // вражеские танки стреляют ( в зависимости от ИИ ) по прохождении заданного времени
    for ( i = 0; i < enemies.length; i++ )
    {
        if ( enemies[i].rocketsTimer < enemies[i].fireRate )
        {
            enemies[i].rocketsTimer++;
        }
        simpleIntelligence( enemies[i] );
        pursuit( enemies[i] );
    }
    // проверка стен для вражеских танков
    for ( i = 0; i < enemies.length; i++ )
    {
        if ( !enemies[i].dead )
        {
            while ( checkWalls( enemies[i], "tank" ))
            {
                getRandomTurn( enemies[i] ); 
            }
        }
    }
    // запуск танков, остановленных при столкновениях со стенами
    for ( i = 0; i < enemies.length; i++ )
    {
        if (( enemies[i].dX == 0 ) && ( enemies[i].dY == 0 ) && ( !enemies[i].dead ) && ( !enemies[i].pursue_enemies ))
        {
            switch ( enemies[i].direction )
            {
                case "right":
                    switch ( getRandomInt( 1, 2 ) )
                    {
                        case 1:
                            enemies[i].turn( "up" );
                        break;
                        case 2:
                            enemies[i].turn( "down" );
                        break;
                    }
                    enemies[i].turn( "left" );
                break;
                case "left":
                    switch ( getRandomInt( 1, 2 ) )
                    {
                        case 1:
                            enemies[i].turn( "up" );
                        break;
                        case 2:
                            enemies[i].turn( "down" );
                        break;
                    }
                    enemies[i].turn( "right" );
                break;
                case "up":
                    switch ( getRandomInt( 1, 2 ) )
                    {
                        case 1:
                            enemies[i].turn( "right" );
                        break;
                        case 2:
                            enemies[i].turn( "left" );
                        break;
                    }
                    enemies[i].turn( "down" );
                break;
                case "down":
                    switch ( getRandomInt( 1, 2 ) )
                    {
                        case 1:
                            enemies[i].turn( "left" );
                        break;
                       case 2:
                            enemies[i].turn( "right" );
                        break;
                    }
                    enemies[i].turn( "up" );
                break;
            }
        }
    }
    // проверка на столкновение вражеских танков и танка игрока
    for ( i = 0; i < enemies.length; i++ )
    {
        for ( j = 0; j <= enemies.length; j++ )
        {
            if ( i >= j )
            {
                continue;
            }
            if ( j == enemies.length )
            {  // while + getRandom = stable bad
                /*while (checkCollision( tank, enemies[i], "tank" ))
                {
                    getRandomTurn( enemies[i] );
                    checkWalls( tank, "tank" );
                    checkWalls( enemies[i], "tank" ); 
                }*/
                if ( checkCollision( tank, enemies[i], "tank" ))
                {
                    tank.x -= tank.dX;
                    tank.y -= tank.dY;
                    enemies[i].x -= enemies[i].dX;
                    enemies[i].y -= enemies[i].dY;
                }
                continue;
            }
            if (( enemies[i].dead ) || ( enemies[j].dead ))
            {
                continue;
            }
            while ( checkCollision( enemies[i], enemies[j], "enemy" ))
            {
                switch ( getRandomInt( 1, 4 ))
                {
                    case 1:
                        enemies[i].turn( "right" );
                        enemies[j].turn( "left" );
                    break;
                    case 2:
                        enemies[i].turn( "left" );
                        enemies[j].turn( "right" );
                    break;
                    case 3:
                        enemies[i].turn( "down" );
                        enemies[j].turn( "up" );
                    break;
                    case 4:
                        enemies[i].turn( "up" );
                        enemies[j].turn( "down" );
                    break;
                }
                checkWalls(enemies[i], "tank");
                checkWalls(enemies[j], "tank");
            }
        }
    }
    // проверка столкновений ракеты
    for ( i = 0; i < enemies.length; i++ )
    {
        for ( j = 0; j < rockets.length; j++ )
        {
            if ((checkCollision( rockets[j], enemies[i], "rocket" )) && 
                ( !rockets[j].dead ) && ( !enemies[i].dead ))
            {
                if ( rockets[j].type == enemies[i].type )
                {
                    rockets.splice( j, 1 );
                }
                else
                {
                    if (!loseLife( enemies[i] ))
                    {
                        rockets.splice( j, 1 );
                        enemies[i].rocketsTimer = 0;
                        destroyObject( enemies[i] );
                    }
                    else
                    {
                        destroyObject( rockets[j] );
                    }
                }
            }
        }
        if (( enemies[i].dead ) && ( enemies[i].frame == enemies[i].anims[enemies[i].currAnim].frames ))
        {
            // удаление танка
            var lastInt = enemies[i].intelligence;
            enemies.splice( i, 1 );
            ENEMIES_TOTAL--;
            // добавление нового танка ( опционально )
            enemies.splice( enemies.length - 1, 0, generateOneEnemy( enemies[enemies.length], lastInt ));
            ENEMIES_TOTAL++;
        }
    }
    // проверка попадания ракет в танк игрока
    for ( i = 0; i < rockets.length; i++ )
    {
        if ( checkCollision( rockets[i], tank, "rocket" ) && ( !rockets[i].dead ) && ( !tank.dead ) )
        {
            if ( rockets[i].type == tank.type )
            {
                rockets.splice( i, 1 );
            } 
            else
            {
                if (!loseLife( tank ))
                {          
                    rockets.splice( i, 1 );
                    destroyObject( tank );
                }
                else
                {
                    destroyObject( rockets[i] );
                }
            }
        }
    }
    // проверка стен для танка игрока
    checkWalls( tank, "tank" );
    // проверка стен для вражеских танков
    for ( i = 0; i < enemies.length; i++ )
    {
        if (( checkWalls( enemies[i], "tank" ) ) && ( !enemies[i].dead ))
        {
            if ( enemies[i].intelligence == "type1" )
            {
                getRandomTurn( enemies[i] );
            }
            else
            {
                if ( enemies[i].pursue_enemies )
                {
                    left( enemies[i] );
                }
                else
                {
                    getRandomTurn( enemies[i] );
                }
            }
        }
    }
    // проверка стен для ракет
    for ( i = 0; i < rockets.length; i++ )
    {
        if (( checkWalls( rockets[i], "rocket" ) ) && ( !rockets[i].dead ))
        {
            destroyObject( rockets[i] );
        }
    }
    // Анимация смерти завершилась, удаляем ракету
    for ( i = 0; i < rockets.length; i++ )
    {
        if (( rockets[i].dead ) && ( rockets[i].frame >= rockets[i].anims[rockets[i].currAnim].frames ))
        {
            rockets.splice ( i, 1 );
        }
    }    
    // вражеские танки меняют свое направление через каждые 1,5 секунды
    enemiesCourseTimer++;
    if ( enemiesCourseTimer > MAX_TIME )
    {
        enemiesCourseTimer = 0;
        course();
    }
    // возможность стрельбы танка игрока
    if ( tank.rocketsTimer < tank.fireRate )
    {
        tank.rocketsTimer++;
    }
    // вражеские танки стреляют ( в зависимости от ИИ ) по прохождении заданного времени
   /* for ( i = 0; i < enemies.length; i++ )
    {
        if ( enemies[i].rocketsTimer < enemies[i].fireRate )
        {
            enemies[i].rocketsTimer++;
        }
        simpleIntelligence( enemies[i] );
        pursuit( enemies[i] );
    }*/
    // проверка окончания анимации смерти для танка игрока
    if (( tank.dead ) && ( tank.frame > tank.anims[tank.currAnim].frames ))
    {
        pause();
    }

}

function play()
{
    draw();
    update();
}

function generateOneEnemy( tankObj, intelligence )
{
    var plus = Math.round(( BLOCK_SIDE - TANK_HEIGHT ) / 2);
    var tankCoord = [];
    generateRndPosition( tankCoord );
    level[tankCoord[0]][tankCoord[1]].type = 0;
    tankObj = new OTank( tankCoord[1] * BLOCK_SIDE + plus, tankCoord[0] * BLOCK_SIDE + plus, 1, 
                         ENEMY_VELOCITY, g_enemyImg, g_tankExplosionImg );
    
    getRandomTurn( tankObj );
    tankObj.intelligence = intelligence;
    
    return tankObj;
}

function generateRndPosition( tankCoord )
{
    tankCoord[0] = getRandomInt( 1, BLOCKS_IN_LVL - 2 );
    tankCoord[1] = getRandomInt( 1, BLOCKS_IN_LVL - 2 );
    while ( level[tankCoord[0]][tankCoord[1]].type != 0 )
    {
        if ( tankCoord[1] == BLOCKS_IN_LVL - 2 )
        {
            tankCoord[1] = 1;
            tankCoord[0]++;
        }
        if ( tankCoord[0] == BLOCKS_IN_LVL - 2 )
        {
            tankCoord[0] = 1;
        }
        tankCoord[1]++;
    }
    level[tankCoord[0]][tankCoord[1]].type = 2;
}

function destroyObject( obj )  // Останавливает объект и включает анимацию смерти
{
    obj.dead = true;
    obj.dX = 0;
    obj.dY = 0;
    obj.currAnim = 'dead';
    obj.frame = 0;
}

function getRandomInt( min, max ) // случайное число в заданном диапазоне
{
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getRandomSpeeds()
{
    // задание случайных скоростей вражеским танкам
    for ( var i = 0; i < enemies.length; i++ )
    {
        getRandomTurn( enemies[i] );
    }
}

function pause()
{
    if ( !gameOver )
    {
        if ( isPlaying )
        {        
            if ( !tank.dead )
            {
                isPlaying = false;
                drawText( "Pause" );
            }
            else
            {
                gameOver = true;
                drawText( "Game Over" );
            }
            clearInterval( playing );
        }
        else
        {
            playing = setInterval( play, 1000 / FPS );
            isPlaying = true;
        }
    }
}

function init() // инициализация канваса и переменных
{
    var canvas = document.getElementById( 'field' );
    canvas.width = BLOCKS_IN_LVL * BLOCK_SIDE;         //ширина холста
    canvas.height = canvas.width;                      //высота холста
    
    if ( canvas.getContext )
    {
        context = canvas.getContext('2d');
        
        g_blocksImg = new Image();                               //картинка с блоками
        g_blocksImg.src = "resourses/images/blocks.png";
        g_tankImg = new Image();                                 //картинка с танком игрока
        g_tankImg.src = "resourses/images/tank.png";            
        g_tankExplosionImg = new Image();                        //взрыв танка
        g_tankExplosionImg.src = "resourses/images/tank_explosion.png";
        g_enemyImg = new Image();                                //картинка с танком врага
        g_enemyImg.src = "resourses/images/enemy.png";  
        g_rocketImg = new Image();                               //картинка с ракетой
        g_rocketImg.src = "resourses/images/rocket.png";
        g_rocketExplosionImg = new Image();                      //взрыв ракеты
        g_rocketExplosionImg.src = "resourses/images/rocket_explosion.png";
        
        generateLevel();
        // генерация случайного расположения танков
        var tankCoord = [];
        var toRemember = [];
        var j = 0;
        var plus = Math.round(( BLOCK_SIDE - TANK_HEIGHT ) / 2);
        generateRndPosition( tankCoord );
        toRemember[j++] = tankCoord[0];
        toRemember[j++] = tankCoord[1];
        tank = new OTank( tankCoord[1] * BLOCK_SIDE + plus, tankCoord[0] * BLOCK_SIDE + plus, 0, 
                          TANK_VELOCITY, g_tankImg, g_tankExplosionImg );
        tankCoord = [];
        changeLifes( tank.lifes );
        for ( var i = 0; i < ENEMIES_TOTAL; i++ )
        {
            generateRndPosition( tankCoord );
            toRemember[j++] = tankCoord[0];
            toRemember[j++] = tankCoord[1];
            enemies[i] = new OTank( tankCoord[1] * BLOCK_SIDE + plus, tankCoord[0] * BLOCK_SIDE + plus, 
                                    1, ENEMY_VELOCITY, g_enemyImg, g_tankExplosionImg );
            enemies[i].intelligence = (i % 2 == 0) ? "type1" : "type1";
            tankCoord = [];
        }
        getRandomSpeeds(); // задание случайных скоростей врагам
        for ( j = 0; j < toRemember.length; j += 2 )
        {
            level[toRemember[j]][toRemember[j + 1]].type = 0;
        }
        toRemember = [];

        playing = setInterval( play, 1000 / FPS );               //отрисовываем FPS раз за секунду
    }
    else
    {
        alert( 'Error!' );
    }
}